﻿using BLL.Interface;
using Common.Extensions;
using DAL.Interface;
using Microsoft.EntityFrameworkCore;
using Model;
using Model.DTO.Article;
using Model.DTO.Public.GetList;
using Model.DTO.Public.OperateId;
using Model.Entity.Article;
using Model.Entity.Article.Relation;
using Model.Entity.Type;
using Model.Entity.User;

namespace BLL
{
    /// <summary>
    /// 文章业务逻辑层
    /// </summary>
    public class ArticleBLL : IArticleBLL
    {
        private readonly IBaseDAL_LONG<TB_Article> _articleDAL;
        private readonly IBaseDAL_LONG<TB_ArticleToType> _articleToTypeDAL;
        private readonly IBaseDAL<TB_ArticleType> _articleTypeDAL;
        private readonly IBaseDAL<TB_User> _userDAL;
        private readonly IBaseDAL<TB_CheckType> _checkTypeDAL;
        private readonly IBaseDAL<TB_StateType> _stateTypeDAL;
        public ArticleBLL(
            IBaseDAL_LONG<TB_Article> articleDAL,
            IBaseDAL_LONG<TB_ArticleToType> articleToTypeDAL,
            IBaseDAL<TB_ArticleType> articleTypeDAL,
            IBaseDAL<TB_User> userDAL,
            IBaseDAL<TB_CheckType> checkTypeDAL,
            IBaseDAL<TB_StateType> stateTypeDAL
            )
        {
            _articleDAL = articleDAL;
            _articleToTypeDAL = articleToTypeDAL;
            _articleTypeDAL = articleTypeDAL;
            _userDAL = userDAL;
            _checkTypeDAL = checkTypeDAL;
            _stateTypeDAL = stateTypeDAL;
        }
        /// <summary>
        /// 添加文章
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> AddArticle(AddArticleDTO param)
        {
            try
            {
                #region 过滤
                var existUser = await _userDAL.GetEntityAllAsync(x => x.Id == param.UserId).Result.AnyAsync();
                if (!existUser)
                {
                    return ResponseMessage.CreateError("用户不存在");
                }
                var articleTypeIds = _articleTypeDAL.GetEntityAllAsync().Result.Select(x => x.Id);
                var notExistArticleTypeIds = param.ArticleTypeIds.Except(articleTypeIds);
                if (notExistArticleTypeIds.Any())
                {
                    return ResponseMessage.CreateError("存在无效的文章类型");
                }
                #endregion
                using var tran = await _articleDAL.BeginTransactionAsync();
                try
                {
                    var article = new TB_Article();
                    param.CopyPropertiesTo(article);
                    article = await _articleDAL.AddEntityAndReturnAsync(article);
                    foreach (var articleTypeId in param.ArticleTypeIds)
                    {
                        var articleToType = new TB_ArticleToType
                        {
                            ArticleId = article.Id,
                            ArticleTypeId = articleTypeId
                        };
                        await _articleToTypeDAL.AddEntityAsync(articleToType);
                    }
                    await tran.CommitAsync();
                    return ResponseMessage.CreateSuccess("添加成功");
                }
                catch
                {
                    await tran.RollbackAsync();
                    throw;
                }
            }
            catch
            {
                return ResponseMessage.CreateError("添加失败");
            }
        }
        /// <summary>
        /// 删除文章
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> DeleteArticle(OperateIdDTO_LONG param)
        {
            try
            {
                if (param.Id > 0)
                {
                    param.Ids.Clear();
                    param.Ids.Add(param.Id);
                    param.Id = 0;
                    return await DeleteArticle(param);
                }
                #region 过滤
                if (param.Ids.Count <= 0)
                {
                    return ResponseMessage.CreateError("文章Id无效");
                }
                #endregion
                using var tran = await _articleDAL.BeginTransactionAsync();
                try
                {
                    foreach (var id in param.Ids)
                    {
                        await _articleDAL.DeleteEntityAsync(id);
                        var articleToTypes = await _articleToTypeDAL.GetEntityAllAsync(x => x.ArticleId == id);
                        foreach (var articleToType in articleToTypes)
                        {
                            await _articleToTypeDAL.DeleteEntityAsync(articleToType);
                        }
                    }
                    await tran.CommitAsync();
                    return ResponseMessage.CreateSuccess("删除成功");
                }
                catch
                {
                    await tran.RollbackAsync();
                    throw;
                }
            }
            catch
            {
                return ResponseMessage.CreateError("删除失败");
            }
        }
        /// <summary>
        /// 编辑文章
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> EditArticle(EditArticleDTO param)
        {
            try
            {
                #region 过滤
                var article = await _articleDAL.GetEntityAllAsync(x => x.Id == param.Id).Result.FirstOrDefaultAsync();
                if (article == null)
                {
                    return ResponseMessage.CreateError("文章不存在");
                }
                var existCheckType = await _checkTypeDAL.GetEntityAllAsync(x => x.Id == param.CheckTypeId).Result.AnyAsync();
                if (!existCheckType)
                {
                    return ResponseMessage.CreateError("审核类型不存在");
                }
                var existStateType = await _stateTypeDAL.GetEntityAllAsync(x => x.Id == param.StateTypeId).Result.AnyAsync();
                if (!existStateType)
                {
                    return ResponseMessage.CreateError("状态类型不存在");
                }
                #endregion
                param.CopyPropertiesTo(article);
                var result = await _articleDAL.EditEntityAsync(article);
                return result ? ResponseMessage.CreateSuccess("编辑成功") : ResponseMessage.CreateError("编辑失败");
            }
            catch
            {
                return ResponseMessage.CreateError("编辑失败");
            }
        }
        /// <summary>
        /// 获取文章列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> GetArticleList(GetListDTO param)
        {
            try
            {
                #region 参数调整
                if (param.Page <= 0)
                {
                    param.Page = 1;
                }
                if (param.Size <= 0)
                {
                    param.Size = 10;
                }
                #endregion
                var articles = await _articleDAL.GetEntityAllAsync(x => x.Title.Contains(param.Query ?? string.Empty));
                int total = await articles.CountAsync();
                var list = await articles.Skip((param.Page - 1) * param.Size).Take(param.Size).ToListAsync();
                return ResponseMessage.CreateSuccess("获取成功", new { total, list });
            }
            catch
            {
                return ResponseMessage.CreateError("获取失败");
            }
        }
        /// <summary>
        /// 绑定文章与类型
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> BindArticleTypes(OperateIdDTO_LONG_INT param)
        {
            try
            {
                #region 过滤
                var existArticle = await _articleDAL.GetEntityAllAsync(x => x.Id == param.Id).Result.AnyAsync();
                if (!existArticle)
                {
                    return ResponseMessage.CreateError("文章不存在");
                }
                var articleTypeIds = _articleTypeDAL.GetEntityAllAsync().Result.Select(x => x.Id);
                var notExistArticleTypeIds = param.Ids.Except(articleTypeIds);
                if (notExistArticleTypeIds.Any())
                {
                    return ResponseMessage.CreateError("存在无效的文章类型");
                }
                #endregion
                var articleToTypeIds = _articleToTypeDAL.GetEntityAllAsync(x => x.ArticleId == param.Id).Result.Select(x => x.ArticleTypeId);
                using var tran = await _articleDAL.BeginTransactionAsync();
                try
                {
                    //解绑文章类型
                    foreach (var articleToTypeId in articleToTypeIds)
                    {
                        if (!param.Ids.Contains(articleToTypeId))
                        {
                            await _articleToTypeDAL.DeleteEntityAsync(articleToTypeId);
                        }
                    }
                    //绑定文章类型
                    foreach (var id in param.Ids)
                    {
                        if (!articleToTypeIds.Contains(id))
                        {
                            await _articleToTypeDAL.AddEntityAsync(new TB_ArticleToType { ArticleId = param.Id, ArticleTypeId = id });
                        }
                    }
                    await tran.CommitAsync();
                    return ResponseMessage.CreateSuccess("绑定成功");
                }
                catch
                {
                    await tran.RollbackAsync();
                    throw;
                }
            }
            catch
            {
                return ResponseMessage.CreateError("绑定失败");
            }
        }
        /// <summary>
        /// 获取文章绑定的文章类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResponseMessage> GetArticleBindArticleType(long id)
        {
            try
            {
                var articleToTypes = await _articleToTypeDAL.GetEntityAllAsync(x => x.ArticleId == id);
                var total = await articleToTypes.CountAsync();
                var list = await articleToTypes.ToListAsync();
                return ResponseMessage.CreateSuccess("获取成功", new { total, list });
            }
            catch
            {
                return ResponseMessage.CreateError("获取失败");
            }
        }
    }
}
